package controller

import (
	"devops/code"
	"devops/controller/validation"
	"devops/middleware"
	"devops/models"
	"devops/service"
	"strings"

	"github.com/gin-gonic/gin"
)

// @Summary 创建计划
// @Tags 构建计划
// @Produce  json
// @Param	param  body  validation.CreateCI  true      "传入参数"
// @Success 200 {object} data.SuccessCreateCI  			"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Failure 13002 {object} data.FailCreateCI     		"错误返回"
// @Router /api/ci/create [post]
func CreateCI(c *gin.Context) {
	var param validation.CreateCI
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	param.Name = strings.TrimSpace(param.Name)
	devops := service.NewDevOps()
	if param.Branch == "" {
		param.Branch = "master"
	}
	job, err := devops.CreateCI(param)
	if err != nil {
		ErrorResponse(c, code.CREATE_JOB_ERR, err.Error())
		return
	}
	// 记录事件
	user := c.MustGet("curUser").(middleware.User)
	go devops.CiEvent(service.CiCreate, &user, *models.GetCIByPIDAndName(param.ProjectId, param.Name))
	SuccessResponse(c, job)
}

// @Summary 更新计划
// @Tags 构建计划
// @Produce  json
// @Param	param  body  validation.UpdateCI  true      "传入参数"
// @Success 200 {object} data.SuccessGetOneCI  			"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Failure 11002 {object} data.FailUpdateCI     		"错误返回"
// @Router /api/ci/update [post]
func UpdateCI(c *gin.Context) {
	var param validation.UpdateCI
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	devops := service.NewDevOps()
	if param.Branch == "" {
		param.Branch = "master"
	}
	job, err := devops.UpdateCI(param)
	if err != nil {
		ErrorResponse(c, code.UPDATE_FAIL, err.Error())
		return
	}
	// 记录事件
	user := c.MustGet("curUser").(middleware.User)
	go devops.CiEvent(service.CiUpdate, &user, *models.GetCIByID(param.CID))
	SuccessResponse(c, job)
}

// @Summary 更新计划名称
// @Tags 构建计划
// @Produce  json
// @Param	param  body  validation.UpdateCiName  true      "传入参数"
// @Success 200 {object} data.SuccessCreateCI  			"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Failure 11002 {object} data.FailUpdateCI     		"错误返回"
// @Router /api/ci/name/update [post]
func UpdateCiName(c *gin.Context) {
	var param validation.UpdateCiName
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	param.Name = strings.TrimSpace(param.Name)
	devops := service.NewDevOps()
	job, err := devops.UpdateCiName(param.CID, param.Name)
	if err != nil {
		ErrorResponse(c, code.UPDATE_FAIL, err.Error())
		return
	}
	// 记录事件
	user := c.MustGet("curUser").(middleware.User)
	go devops.CiEvent(service.CiUpdate, &user, *models.GetCIByID(param.CID))
	SuccessResponse(c, job)
}

// @Summary 更新Jenkinsfile
// @Tags 构建计划
// @Produce  json
// @Param	param  body  validation.UpdateJksfile  true "传入参数"
// @Success 200 {object} data.SuccessCreateCI  			"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Failure 11002 {object} data.FailUpdateCI     		"错误返回"
// @Router /api/ci/updateJksfile [post]
func UpdateJksfile(c *gin.Context) {
	var param validation.UpdateJksfile
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	devops := service.NewDevOps()

	job, err := devops.UpdateJksfile(param.CID, param.Jenkinsfile)
	if err != nil {
		ErrorResponse(c, code.UPDATE_FAIL, err.Error())
		return
	}
	// 记录事件
	user := c.MustGet("curUser").(middleware.User)
	go devops.CiEvent(service.CiUpdate, &user, *models.GetCIByID(param.CID))
	SuccessResponse(c, job)
}

// @Summary 删除构建计划
// @Tags 构建计划
// @Produce  json
// @Param	param  body  validation.DeleteCI  true      "传入参数"
// @Success 200 {object} data.SuccessDeleteCI  			"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Failure 11001 {object} data.FailDeleteCI     		"错误返回"
// @Router /api/ci/delete [post]
func DeleteCI(c *gin.Context) {
	var param validation.DeleteCI
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	devops := service.NewDevOps()
	err := devops.DeleteCI(param.ProjectID, param.CID)
	if err != nil {
		ErrorResponse(c, code.DELETE_JOB_ERR, err.Error())
		return
	}
	// 记录事件
	SuccessResponse(c, "删除成功")
}

// @Summary 获取项目下的构建计划列表
// @Tags 构建计划
// @Produce  json
// @Param	param  query  validation.GetProjectCI  true "创建参数"
// @Success 200 {object} data.SuccessGetCI  		"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Router /api/ci/all [get]
func GetProjectCI(c *gin.Context) {
	var param validation.GetProjectCI
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	validation.CheckPage(&param.Page)
	devops := service.NewDevOps()
	cis, total := devops.GetProjectCI(param.ProjectId, param.Page.Page, param.Page.PageSize, param.SearchWord)
	SuccessPaginateResponse(c, cis, total, param.Page.Page, param.Page.PageSize)
}

// @Summary 获取单个构建计划
// @Tags 构建计划
// @Produce  json
// @Param	param  query  validation.GetCI  true "创建参数"
// @Success 200 {object} data.SuccessGetOneCI  	 "成功返回"
// @Failure 10000 {object} data.ParamError     	 "错误返回"
// @Router /api/ci/one [get]
func GetOneCI(c *gin.Context) {
	var param validation.GetCI
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	devops := service.NewDevOps()
	SuccessResponse(c, devops.GetOneCI(param.CID))
}

// @Summary 获取某计划的基础信息
// @Tags 构建计划
// @Produce  json
// @Param	param  query  validation.GetCI  true "创建参数"
// @Success 200 {object} data.SuccessGetOneCIBaseInfo  	 "成功返回"
// @Failure 10000 {object} data.ParamError     	 "错误返回"
// @Router /api/ci/one/baseinfo [get]
func GetOneCIBaseInfo(c *gin.Context) {
	var param validation.GetCI
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	devops := service.NewDevOps()
	SuccessResponse(c, devops.GetOneCIBaseInfo(param.CID))
}

// @Summary Jenkinsfile 转换 Json
// @Tags 构建计划
// @Produce  json
// @Param	body  body  validation.ToJson  true  		"创建参数"
// @Success 200 {object} data.SuccessToJson  			"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Failure 13000 {object} data.FailToJson     			"错误返回"
// @Router /api/ci/jenkins/tojson [post]
func ToJson(c *gin.Context) {
	var param validation.ToJson
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}

	devops := service.NewDevOps()
	fileJson, err := devops.ToJson(param.Jenkinsfile)
	if err != nil {
		ErrorResponse(c, code.CONVERSION_FAIL, nil)
		return
	}
	SuccessResponse(c, fileJson)
}

// @Summary Json 转换 Jenkinsfile
// @Tags 构建计划
// @Produce  json
// @Param	body  body  validation.ToJenkinsFile  true  "创建参数"
// @Success 200 {object} data.SuccessToJson  	  		"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Failure 13000 {object} data.FailToJson     			"错误返回"
// @Router /api/ci/jenkins/tojenkinsfile [post]
func ToJenkinsfile(c *gin.Context) {
	var param validation.ToJenkinsFile
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}

	devops := service.NewDevOps()
	jenkinsfile, err := devops.ToJenkinsfile(param.JenkinsfileJson)
	if err != nil {
		ErrorResponse(c, code.CONVERSION_FAIL, nil)
		return
	}
	SuccessResponse(c, jenkinsfile)
}

// @Summary 验证 Jenkinsfile 的 json 格式
// @Tags 构建计划
// @Produce  json
// @Param	body  body  validation.ToJenkinsFile  true  "传入参数"
// @Success 200 {object} data.SuccessToJson  	  		"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Failure 13000 {object} data.FailToJson     			"错误返回"
// @Router /api/ci/jenkins/validateJson [post]
func ValidateJson(c *gin.Context) {
	var param validation.ToJenkinsFile
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}

	devops := service.NewDevOps()
	jenkinsfile, err := devops.ValidateJson(param.JenkinsfileJson)
	if err != nil {
		ErrorResponse(c, code.CONVERSION_FAIL, nil)
		return
	}
	SuccessResponse(c, jenkinsfile)
}
